console.log('hello ts');
console.log(2222);
let age:number = 0;
let lname:string = 'ggg';
let arr1:number[] = [1,2,3]; 
let person:[string,number] = ['zhang',34];//元组tuple,和数组很像，表示已知数量和类型的数组；

enum Gender {
  MALE,
  FEMALE
}//普通枚举类型
const enum Colors{
  RED,
  YELLOW,
  BLUE
};//常量枚举

//任意类型any
//ts给DOM，BOM提供了类型声明
let root:any = document.getElementById('root');
root.style.color = 'red';

let root1:HTMLElement | null = document.getElementById('root');
//!代表非空断言，告诉ts root1不可能为空
root1!.style.color = 'green';

//null和undefined是其他类型的子类型，可以赋值给其他类型
// let x:number;
// x = 1;
// //如果tsconfig中strictNullChecks设置为true,就不能赋值undefined null给x
// x = undefined;
// x = null;

let y:number |undefined | null;
y = 2;
y = undefined;
y = null;

//void空 表示没有任何类型
function greeting(name:string):void{
  console.log(name);
}

//never 永远不会出现的值，是其他类型的子类型
//作为不会返回函数的返回 类型
function err(message:string):never{
  console.log(111);
  throw new Error('error');
  console.log('end');
}
let ret:never = err('hello');
//还表示永远无法达到终点
//never和void区别：void可以赋值null或undefined, 而never不包含任何值
//定义void的函数能正常运行，never定义的函数永远无法返回，无法中止
function loop():never {
  while(true){
  }
}

//类型推断 TS会根据赋的值猜类型
let a = 1;
//包装对象 Wrapper Object
//JS里类型分两种，基本类型和引用类型，基本类型是没有属性和方法的
let name2 = 'gg';
console.log(name2.toUpperCase());//当你在调用基本类型方法的时候，JS会迅速对原始类型进行包装成对象，调用的是对象上的方法,等同于下面：
new String(name2).toUpperCase();

//联合类型
let name3:string | number;

//类型断言：可以把联合类型的变量指定为更加具体的类型
let name5: string | number;
(name5 as string).length;
(name5 as number).toFixed(2);

//字面量类型：可以把字符串、数字、布尔值组成一个联合类型
type myType = 1 | 'one' | true;
let t:myType = 1;
let t2:myType = true;

//字面量类型和联合类型：字面量是值的联合，联合是类型的联合